#!/bin/bash

run_user=`whoami`

if [ 'X'$run_user != 'X''root' ]
then
    echo 'Error! should run me with root...'
    exit 1
fi

cnt=`ps aux | grep redis | grep -v $0 | grep -v 'grep' | wc -l`
if [ $cnt -gt 0 ]
then
    echo "ERROR! redis may be running, exit..."
    exit 10
fi

# absolute path of redis tarball used. if not give, will download redis tarball from Internet
TARBALL_PATH=''

# absolute path of redis configuration file used, defaults to '/tmp/redis_env.config'
REDIS_CONF_PATH=''

# absolute path to install redis
INSTALL_HOME=''


usage() { 
  echo -e "
Usage:
  $0 [-f ARCHIVE_TARBARR_PATH] [-c CONFIGURATION_PATH]
Common options:
  -f,  file, absolute path of archive tarball. Without -f options will download tarball from Internet
  -h,  home, absolute path of install home, default to "'`/home/redis/redis-server`'"
  -c,  conf, absolute path of configuration file, default to "'`/tmp/redis_env.config`'"
" 1>&2; exit 1;
}

while getopts ":f:h:c:" o; do
    case "${o}" in
        f)
            v=${OPTARG}
            if [ 'X'$v == 'X' ]
            then
              usage
            else
              TARBALL_PATH=${OPTARG}
            fi
            ;;
        h)
            v=${OPTARG}
            if [ 'X'$v == 'X' ]
            then
              usage
            else
              INSTALL_HOME=${OPTARG}
            fi
            ;;
        c)
            v=${OPTARG}
            if [ 'X'$v == 'X' ]
            then
              usage
            else
              REDIS_CONF_PATH=${OPTARG}
            fi
            ;;
        *)
            usage
            ;;
    esac
done
shift $((OPTIND-1))


if [ 'X'${TARBALL_PATH} == 'X' ]
then
    # version used when no tarball give
    DEFAULT_VERSION=6.0.16

    tarball="redis-${DEFAULT_VERSION}.tar.gz"
    TARBALL_PATH="/tmp/${tarball}"

    if [ -f ${TARBALL_PATH} ]
    then
        rm -rf ${TARBALL_PATH}
    fi
    echo "not give redis tarball absolute path, will download ${tarball} from Internet"
    # https://download.redis.io/releases/redis-6.0.16.tar.gz
    curl https://download.redis.io/releases/${tarball} --output ${TARBALL_PATH}
fi
if [ ! -f ${TARBALL_PATH} ]
then
    echo "ERROR! redis tarball:${TARBALL_PATH} not found, exit..."
    exit 11
fi


if [ 'X'${INSTALL_HOME} == 'X' ]
then
    INSTALL_HOME='/home/redis/redis-server'
    echo "not give redis install home absolute path, will use default path: ${INSTALL_HOME}"
fi
if [ -d ${INSTALL_HOME} ]
then
    echo "Error! redis home dir ${INSTALL_HOME} exists, should clean redis env before re-install..."
    exit 10
fi

if [ 'X'${REDIS_CONF_PATH} == 'X' ]
then
    REDIS_CONF_PATH='/tmp/redis_env.config'
    echo "not give redis configuration file absolute path, will use default path: ${REDIS_CONF_PATH}"
fi

install_libs_centos(){
    cd /
    yum update -y
    yum install gcc gcc-c++ make -y

    # install gcc 9 and enable it temporary
    yum -y install centos-release-scl
    yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
    echo 'install gcc 9 in /opt/rh/devtoolset-9'
    source /opt/rh/devtoolset-9/enable
    echo 'gcc 9 enabled, this will auto recover after current bash exit'
    gcc -v

    # install dos2unix to process some text files
    yum install dos2unix -y
}

install_libs_ubuntu(){
    cd /
    apt-get update -y
    apt-get install -y build-essential

    # install dos2unix to process some text files
    apt-get install dos2unix -y
}

is_centos=`awk -F '=' '/PRETTY_NAME/ { print $2 }' /etc/os-release | grep -i centos | wc -l`
is_ubuntu=`awk -F '=' '/PRETTY_NAME/ { print $2 }' /etc/os-release | grep -i ubuntu | wc -l`

if [ $is_centos -gt 0 ]
then
    # install libs
    install_libs_centos
fi

if [ $is_ubuntu -gt 0 ]
then
    # install libs
    install_libs_ubuntu
fi

# add redis user and set passwd
groupadd redis
useradd -g redis redis
echo redis:redis.123 | chpasswd
echo 'you can use `su - redis` to login as user `redis`, and password is: `redis.123`'

# # remove user redis from sudoers
# cat /etc/sudoers > /etc/sudoers_bak
# cat /etc/sudoers_bak | grep -v 'redis' > /etc/sudoers

if [ ! -d ${INSTALL_HOME} ]
then
    mkdir -p ${INSTALL_HOME}
fi


cd ${INSTALL_HOME}
mkdir bin
mkdir conf
mkdir logs
mkdir redis_package # tmp dir to make redis binary

tar -xzvf ${TARBALL_PATH} -C ${INSTALL_HOME}/redis_package --strip-components 1

cd ${INSTALL_HOME}/redis_package/src
make distclean
make install  PREFIX=${INSTALL_HOME}

# exit with error if make redis fail
ret=$?

if [ 'X'$ret != 'X'0 ]
then
    make distclean
    echo 'Error! make redis failed...'
    exit 9
fi


# add ln for redis-*
rm -rf /usr/bin/redis-server
ln -s ${INSTALL_HOME}/bin/redis-server /usr/bin/redis-server
rm -rf /usr/bin/redis-cli
ln -s ${INSTALL_HOME}/bin/redis-cli /usr/bin/redis-cli
rm -rf /usr/bin/redis-sentinel
ln -s ${INSTALL_HOME}/bin/redis-sentinel /usr/bin/redis-sentinel


# load redis from custom configs files
# clear previous env
export redis_port=
export redis_password=

if [ -f ${REDIS_CONF_PATH} ]
then
    dos2unix ${REDIS_CONF_PATH}
    . ${REDIS_CONF_PATH}
else
    echo "${REDIS_CONF_PATH} not found, will use redis default port and password"
fi

if [ 'X'${redis_port} == 'X' ]
then
    redis_port=6379
    echo "use redis default port: ${redis_port}"
fi

if [ 'X'${redis_password} == 'X' ]
then
    redis_password='redis.123'
    echo "use redis default password: ${redis_password}"
fi

# cp redis default conf file to conf dir
cd ${INSTALL_HOME}/conf
# use port for conf filename, for launching multi servers on one host
cat ${INSTALL_HOME}/redis_package/redis.conf > redis_${redis_port}.conf

# set some config
echo "" >> redis_${redis_port}.conf
echo "# configs added when install redis" >> redis_${redis_port}.conf

# run redis server as daemon
sed -i "s/daemonize no/#daemonize no/g" redis_${redis_port}.conf
echo "daemonize yes" >> redis_${redis_port}.conf

# redis server listen to all clients from internet
sed -i "s/bind 127.0.0.1/#bind 127.0.0.1/g" redis_${redis_port}.conf
echo "bind 0.0.0.0" >> redis_${redis_port}.conf

# rdb file name
sed -i "s|dbfilename dump.rdb|#dbfilename dump.rdb|g" redis_${redis_port}.conf
echo "dbfilename dump_${redis_port}.rdb" >> redis_${redis_port}.conf

# aop file name
sed -i "s|appendfilename ""appendonly.aof""|#appendfilename ""appendonly.aof""|g" redis_${redis_port}.conf
echo "appendfilename ""appendonly_${redis_port}.aof" >> redis_${redis_port}.conf

# log to ../logs/redis-server.log
sed -i 's/logfile ""/#logfile ""/g' redis_${redis_port}.conf
echo "logfile ../logs/redis-server-${redis_port}.log" >> redis_${redis_port}.conf

cd ${INSTALL_HOME}/conf
if [ 'X'${redis_port} != 'X' ]
then
    sed -i "s/port 6379/#port 6379/g" redis_${redis_port}.conf
    echo "port ${redis_port}" >> redis_${redis_port}.conf
    echo "use config: redis_port is: ${redis_port}"
fi

if [ 'X'${redis_password} != 'X' ]
then
    echo "requirepass ${redis_password}" >> redis_${redis_port}.conf
    echo "use config: redis_password is: ${redis_password}"
fi

# change pidfile name
# redis process start with user redis, if pidfile dir can not write, it can startup normally but will not generate pidfile
sed -i "s|pidfile /var/run/redis_6379.pid|#pidfile /var/run/redis_6379.pid|g" redis_${redis_port}.conf
echo "pidfile ${INSTALL_HOME}/bin/redis_${redis_port}.pid" >> redis_${redis_port}.conf

# generate start/stop tools
cd ${INSTALL_HOME}
echo "cd ${INSTALL_HOME}/bin && ./redis-server ../conf/redis_${redis_port}.conf" > start_up_${redis_port}.sh
chmod 750 start_up_${redis_port}.sh
echo "cd ${INSTALL_HOME}/bin && ./redis-cli -h 127.0.0.1 -p ${redis_port} -a ${redis_password} shutdown" > stop_${redis_port}.sh
chmod 750 stop_${redis_port}.sh

cd ${INSTALL_HOME}
rm -rf ${INSTALL_HOME}/redis_package

# chg files owner to user redis
chown -R redis:redis ${INSTALL_HOME}
cd /home/
chown -R redis:redis /home/redis

# use user redis to start redis-server
su - redis <<EOF
sh ${INSTALL_HOME}/start_up_${redis_port}.sh

sleep 5

echo "redis-server process start, with configuration in ${INSTALL_HOME}/conf. see log in ${INSTALL_HOME}/logs to confirm redis-server status"
EOF
